import service
import uthread
import blue
import log
import util
import trinity
import appUtils
import base
import uiutil
import uiconst
import uicls
NUMPAD_KEYS = []
for num in range(0, 10):
    NUMPAD_KEYS.append(getattr(uiconst, ('VK_NUMPAD%s' % num), (num + 96)))

RENAMEMAP = {'CONTROL': 'CTRL',
 'MENU': 'ALT',
 'MBUTTON': 'MOUSE3',
 'XBUTTON1': 'MOUSE4',
 'XBUTTON2': 'MOUSE5',
 'SNAPSHOT': 'PRINTSCREEN',
 'NEXT': 'PAGEDOWN',
 'PRIOR': 'PAGEUP'}

class CommandMapping():
    __guid__ = 'util.CommandMapping'

    def __init__(self, callback, shortcut, category = None, isLocked = False, description = None, enabled = True, ignoreModifierKey = False, repeatable = False):
        self.callback = callback
        self.name = self.callback.func_name
        self.SetShortcut(shortcut)
        self.category = (category or mls.UI_GENERIC_GENERAL)
        self.description = description
        self.isLocked = isLocked
        self.ignoreModifierKey = ignoreModifierKey
        self.repeatable = repeatable



    def __repr__(self):
        return ("<util.CommandMapping instance -  name='%s', shortcut='%s', callback=%s>" % (self.name,
         self.shortcut,
         self.callback))



    def GetShortcutAsString(self):
        if not self.shortcut:
            return ''
        else:
            retString = ''
            for key in self.shortcut:
                newKey = ', '.join([ each[3:] for each in dir(uiconst) if each.startswith('VK_') ])
                newKey = RENAMEMAP.get(newKey, newKey)
                retString += ('%s-' % newKey)

            retString = retString[:-1]
            return retString



    def GetDescription(self):
        name = self.callback.func_name
        if self.description:
            return self.description
        else:
            if name.startswith('Cmd'):
                return getattr(mls, ('UI_CMD_' + name[3:].upper()), None)
            if name.startswith('WinCmd'):
                return getattr(mls, ('UI_CMD_' + name[6:].upper()), None)
            return getattr(mls, ('UI_CMD_' + name.upper()), None)



    def SetShortcut(self, shortcut):
        self.shortcut = self._ValidateShortcut(shortcut)



    def _ValidateShortcut(self, shortcut):
        if (shortcut is None):
            return 
        else:
            if (type(shortcut) is int):
                shortcut = (shortcut)
            return shortcut



    def GetAccelerator(self):
        if not self.shortcut:
            return 
        else:
            vkey = self.shortcut[-1]
            shortcutModKeys = self.shortcut[:-1]
            modKeys = []
            for modKey in uiconst.MODKEYS:
                modKeys.append((modKey in shortcutModKeys))

            return (tuple(modKeys), vkey)




class CommandMap():

    def __init__(self, defaultCmds = [], customCmds = {}):
        self.commandsByName = {}
        self.commandsByShortcut = {}
        self.accelerators = {}
        self.customCmds = customCmds
        for c in defaultCmds:
            self.AddCommand(c)




    def AddCommand(self, command):
        if (command.name in self.customCmds):
            command.shortcut = self.customCmds[command.name]
            command.shortcut = self._ModernizeOldTypeShortcut(command.shortcut)
        if (self.GetCommandByName(command.name) is None):
            self.commandsByName[command.name] = command
            if (command.shortcut is not None):
                self.commandsByShortcut[command.shortcut] = command
        else:
            log.LogWarn(('Trying to add the same command twice: %s' % command.name))



    def RemapCommand(self, cmdname, newShortcut = None):
        if newShortcut:
            newShortcut = tuple(newShortcut)
        cmd = self.GetCommandByName(cmdname)
        self.UnloadAccelerator(cmd)
        oldShortcut = cmd.shortcut
        if (oldShortcut and (oldShortcut in self.commandsByShortcut)):
            self.commandsByShortcut.pop(tuple(cmd.shortcut))
        self.customCmds[cmdname] = newShortcut
        if newShortcut:
            self.commandsByShortcut[newShortcut] = cmd
        settings.user.cmd.customCmds[cmdname] = newShortcut
        cmd.SetShortcut(newShortcut)
        self.LoadAccelerator(cmd)



    def _ModernizeOldTypeShortcut(self, shortcut):
        if ((not shortcut) or (len(shortcut) != 4)):
            return shortcut
        else:
            for i in xrange(3):
                if (shortcut[i] not in (0, 1)):
                    return shortcut

            newShortcut = []
            if shortcut[0]:
                newShortcut.append(uiconst.VK_CONTROL)
            if shortcut[1]:
                newShortcut.append(uiconst.VK_MENU)
            if shortcut[2]:
                newShortcut.append(uiconst.VK_SHIFT)
            try:
                vkKey = getattr(uiconst, ('VK_%s' % shortcut[-1].upper()))
            except:
                return 
            newShortcut.append(vkKey)
            return tuple(newShortcut)



    def GetAllCommands(self):
        return self.commandsByName.values()



    def Reset(self):
        self.UnloadAccelerators()



    def GetAllUnmappedCommands(self):
        retCmds = []
        for c in self.commandsByName.values():
            if (c.shortcut is None):
                retCmds.append(c)

        return retCmds



    def GetAllMappedCommands(self):
        retCmds = []
        for c in self.commandsByName.values():
            if (c.shortcut is not None):
                retCmds.append(c)

        return retCmds



    def GetCommandByShortcut(self, shortcut):
        return self.commandsByShortcut.get(shortcut)



    def GetCommandByName(self, cmdname):
        return self.commandsByName.get(cmdname)



    def GetCommandCategoryNames(self):
        categories = []
        for c in self.GetAllCommands():
            if (c.category not in categories):
                categories.append(c.category)

        return categories



    def UnloadAcceleratorsByCategory(self, category):
        for cmd in self.commandsByName.values():
            if (cmd.category == category):
                self.UnloadAccelerator(cmd)




    def LoadAcceleratorsByCategory(self, category):
        for cmd in self.commandsByName.values():
            if (cmd.category == category):
                self.LoadAccelerator(cmd)




    def LoadAccelerator(self, cmd):
        accelerator = cmd.GetAccelerator()
        if (accelerator is None):
            return 
        self.accelerators[accelerator] = cmd



    def UnloadAccelerator(self, cmd):
        accelerator = cmd.GetAccelerator()
        if ((accelerator is None) or (accelerator not in self.accelerators)):
            return 
        del self.accelerators[accelerator]



    def LoadAllAccelerators(self):
        for c in self.GetAllCommands():
            self.LoadAccelerator(c)




    def UnloadAllAccelerators(self):
        for c in self.commandsByName.values():
            self.UnloadAccelerator(c)





class CommandService(service.Service):
    __guid__ = 'svc.cmd'
    __update_on_reload__ = 1
    __notifyevents__ = ['OnSessionChanged']

    def Run(self, memStream = None):
        service.Service.Run(self, memStream)
        self.Reload()



    def Reload(self, forceGenericOnly = False):
        if not settings.user.cmd.customCmds:
            settings.user.cmd.customCmds = {}
        self.defaultShortcutMapping = self.SetDefaultShortcutMappingCORE()
        self.defaultShortcutMapping.extend(self.SetDefaultShortcutMappingGAME())
        self.CheckDuplicateShortcuts()
        if hasattr(self, 'commandMap'):
            self.commandMap.UnloadAllAccelerators()
        self.commandMap = CommandMap(defaultCmds=self.defaultShortcutMapping, customCmds=settings.user.cmd.customCmds)
        if ((session.charid is not None) and (forceGenericOnly is False)):
            self.commandMap.LoadAllAccelerators()
        else:
            self.commandMap.LoadAcceleratorsByCategory(mls.UI_GENERIC_GENERAL)



    def Stop(self, stream):
        service.Service.Stop(self)



    def CheckDuplicateShortcuts(self):
        for cmd in self.defaultShortcutMapping:
            for cmdCheck in self.defaultShortcutMapping:
                if cmdCheck.shortcut:
                    sameName = (cmdCheck.name == cmd.name)
                    sameShortcut = (cmdCheck.shortcut == cmd.shortcut)
                    if (sameShortcut and (not sameName)):
                        self.LogError('Same default shortcut used for multiple commands:', cmd)





    def OnSessionChanged(self, isRemote, sess, change):
        if ('userid' in change):
            self.Reload()
        if ('charid' in change):
            self.commandMap.LoadAllAccelerators()



    def SetDefaultShortcutMappingCORE(self):
        ret = []
        c = util.CommandMapping
        CTRL = uiconst.VK_CONTROL
        ALT = uiconst.VK_MENU
        SHIFT = uiconst.VK_SHIFT
        m = [c(self.OnReturn, uiconst.VK_RETURN, description=mls.UI_GENERIC_CONFIRM),
         c(self.OnCtrlA, (CTRL, uiconst.VK_A), description=mls.UI_CMD_SELECTALL),
         c(self.OnCtrlC, (CTRL, uiconst.VK_C), description=mls.UI_CMD_COPY),
         c(self.OnCtrlX, (CTRL, uiconst.VK_X), description=mls.UI_CMD_CUT),
         c(self.OnCtrlV, (CTRL, uiconst.VK_V), description=mls.UI_CMD_PASTE),
         c(self.OnEsc, uiconst.VK_ESCAPE, description=mls.UI_CMD_CLOSEMODALWINDOWSANDOPENCONFIGMENU),
         c(self.PrintScreen, uiconst.VK_SNAPSHOT, description=mls.UI_CMD_PRINTSCREEN),
         c(self.OnCtrlShiftTab, (CTRL,
          SHIFT,
          uiconst.VK_TAB), description=mls.UI_CMD_BROWSEWINDOWMENUUPWARDS),
         c(self.OnCtrlTab, (CTRL, uiconst.VK_TAB), description=mls.UI_CMD_BROWSEWINDOWMENU),
         c(self.OnTab, uiconst.VK_TAB, description=mls.UI_CMD_TABBETWEENEDITFIELDS),
         c(self.OnShiftTab, (SHIFT, uiconst.VK_TAB), description=mls.UI_CMD_TABBETWEENEDITFIELDS)]
        for cm in m:
            cm.category = mls.UI_GENERIC_GENERAL
            cm.isLocked = True
            ret.append(cm)

        m = [c(self.CmdQuitGame, (ALT,
          SHIFT,
          uiconst.VK_Q)),
         c(self.CmdLogOff, None),
         c(self.CmdToggleAudio, (CTRL,
          ALT,
          SHIFT,
          uiconst.VK_F12)),
         c(self.WinCmdToggleWindowed, (ALT, uiconst.VK_RETURN)),
         c(self.CmdCloseAllWindows, (CTRL,
          ALT,
          uiconst.VK_W)),
         c(self.CmdMinimizeAllWindows, None),
         c(self.CmdMinimizeActiveWindow, None),
         c(self.CmdCloseActiveWindow, (CTRL, uiconst.VK_W)),
         c(self.CmdResetMonitor, (CTRL,
          ALT,
          uiconst.VK_RETURN)),
         c(self.OpenMonitor, (CTRL,
          ALT,
          SHIFT,
          uiconst.VK_M))]
        for cm in m:
            cm.category = mls.UI_GENERIC_GENERAL
            ret.append(cm)

        return ret



    def SetDefaultShortcutMappingGAME(self):
        return []



    def HasCommand(self, cmdname):
        avail = self.GetAvailableCmds()
        return bool((cmdname in avail))



    def EditCmd(self, cmdname):
        if self.IsLocked(cmdname):
            uicore.Message('ShortcutLocked')
            return 
        command = self.commandMap.GetCommandByName(cmdname)
        self.MapCmd(cmdname)



    def MapCmd(self, cmdname, c = 0, a = 0, s = 0, vkey = None):
        if (vkey is not None):
            key = self.GetKeyNameFromVK(vkey)
        else:
            key = ''
        self.mappingcmdname = cmdname
        wnd = uiutil.GetFormWindow('Add Shortcut')
        cb1 = uicls.Checkbox(text='Control', parent=wnd.sr.content, checked=c, configName='ctrl')
        uiutil.AddFormControl(wnd, cb1, 'ctrl', None)
        cb2 = uicls.Checkbox(text='Alt', parent=wnd.sr.content, checked=a, configName='alt')
        uiutil.AddFormControl(wnd, cb2, 'alt', None)
        cb3 = uicls.Checkbox(text='Shift', parent=wnd.sr.content, checked=s, configName='shift')
        uiutil.AddFormControl(wnd, cb3, 'shift', None)
        edit = uicls.SinglelineEdit(parent=wnd.sr.content, maxLength=20, setvalue=key)
        uiutil.AddFormControl(wnd, edit, 'key', None)
        uiutil.AddFormErrorCheck(wnd, uicore.cmd.MapCmdErrorCheck)
        if (wnd.ShowModal() == uiconst.ID_OK):
            retval = wnd.result
            setting = (retval['ctrl'],
             retval['alt'],
             retval['shift'],
             retval['key'].lower())
            self.customCmds[cmdname] = setting
            sm.ScatterEvent('OnMapShortcut', cmdname, *setting)
            self.Reload()
        self.mappingcmdname = None



    def CheckKeyDown(self, edit, vkey, flag):
        if (vkey == uiconst.VK_RETURN):
            return 
        edit.SetValue(self.GetKeyNameFromVK(vkey))



    def MapCmdErrorCheck(self, retval):
        return ''



    def ClearMappedCmd(self, cmdname, showMsg = 1):
        if self.IsLocked(cmdname):
            if showMsg:
                uicore.Message('ShortcutLocked')
            return 
        self.commandMap.RemapCommand(cmdname, None)
        sm.ScatterEvent('OnMapShortcut', cmdname, None, None, None, None)



    def RestoreDefaults(self):
        settings.user.cmd.customCmds = {}
        self.Reload()
        sm.ScatterEvent('OnRestoreDefaultShortcuts')



    def IsLocked(self, cmdname):
        command = self.commandMap.GetCommandByName(cmdname)
        if (command and command.isLocked):
            return True
        else:
            return False



    def IsTaken(self, cmdname):
        return (self.GetFuncByShortcut(cmdname) is None)



    def MapKeys(self, VK):
        if (VK in NUMPAD_KEYS):
            num = NUMPAD_KEYS.index(VK)
            VK = getattr(uiconst, ('VK_%s' % num))
        return VK



    def GetCommandCategoryNames(self):
        return self.commandMap.GetCommandCategoryNames()



    def GetKeyNameFromVK(self, VK):
        VK = self.MapKeys(VK)
        return ', '.join([ each[3:] for each in dir(uiconst) if each.startswith('VK_') ])



    def GetVKFromChar(self, char):
        return [ each for each in dir(uiconst) if each.startswith('VK_') ]



    def GetFuncByShortcut(self, shortcut):
        command = self.commandMap.GetCommandByShortcut(shortcut)
        if command:
            return command.name



    def GetShortcutByFuncName(self, funcname, format = False):
        command = self.commandMap.GetCommandByName(funcname)
        if command:
            if format:
                return command.GetShortcutAsString()
            else:
                return command.shortcut
        else:
            return 



    def GetShortcutStringByFuncName(self, funcname):
        command = self.commandMap.GetCommandByName(funcname)
        if command:
            return command.GetShortcutAsString()
        else:
            return ''



    def GetShortcutByString(self, stringfunc):
        command = self.commandMap.GetCommandByName(stringfunc)
        if (command and command.shortcut):
            return command.GetShortcutAsString()



    def UnpackFuncName(self, funcname):
        (nameSpace, className, funcname,) = funcname.split('.')
        return funcname



    def FuncToDesc(self, funcname):
        command = self.commandMap.GetCommandByName(funcname)
        if command:
            return command.GetDescription()
        else:
            return ''



    def GetFuncName(self, cmdname):
        cmdname = cmdname.lower().strip()
        for letter in ('_', ' '):
            while (cmdname.find((letter * 2)) >= 0):
                cmdname = cmdname.replace((letter * 2), letter)

            _cmdname = cmdname.split(letter)
            cmdname = ''
            for part in _cmdname:
                cmdname += ('%s%s' % (part[0].upper(), part[1:]))


        return cmdname



    def GetAvailableCmds(self, reload = False):
        if ((not getattr(self, 'availableCmds', None)) or reload):
            self.availableCmds = []
            for cmdattr in dir(self):
                if ((cmdattr[:4] == 'Open') or (cmdattr[:3] == 'Cmd')):
                    if not self.IsAvailableFunction(self, cmdattr):
                        continue
                    self.availableCmds.append(cmdattr)
                if ((cmdattr[:6] == 'WinCmd') and (not blue.win32.IsTransgaming())):
                    self.availableCmds.append(cmdattr)
                if ((cmdattr[:6] == 'QAOpen') or (cmdattr[:5] == 'QACmd')):
                    self.availableCmds.append(cmdattr)

        return self.availableCmds



    def IsAvailableFunction(self, fromWhere, cmdattr, *args):
        function = getattr(fromWhere, cmdattr, None)
        if (function is None):
            return False
        else:
            availabiltyCheck = getattr(function, 'availabiltyCheck', None)
            if (availabiltyCheck and (not availabiltyCheck())):
                return False
            return True



    def GetActiveCmds(self):
        return self.commandMap.GetAllMappedCommands()



    def GetUnmappedCmds(self):
        return self.commandMap.GetAllUnmappedCommands()



    def GetCustomCmd(self, cmdname):
        return self.customCmds.get(cmdname, None)



    def Execute(self, cmdname, cmdNameExact = False):
        if not cmdNameExact:
            cmdname = cmdname.lower()
            if (cmdname[0] == '/'):
                cmdname = cmdname[1:]
            funcName = self.GetFuncName(cmdname)
        else:
            funcName = cmdname
        func = getattr(self, funcName, None)
        if (func is not None):
            apply(func)
            return ('%s executed' % cmdname)



    def CheckCtrlUp(self, wnd, msgID, ckey):
        chooseWndMenu = getattr(self, 'chooseWndMenu', None)
        if (chooseWndMenu and ((not chooseWndMenu.destroyed) and (chooseWndMenu.state != uiconst.UI_HIDDEN))):
            chooseWndMenu.ChooseHilited()
        self.chooseWndMenu = None
        return 1



    def _AppQuitGame(self):
        blue.pyos.Quit('User requesting close')



    def CmdQuitGame(self):
        if (uicore.Message('AskQuitGame', {}, uiconst.YESNO, uiconst.ID_YES) == uiconst.ID_YES):
            uicore.SaveSettings()
            self._AppQuitGame()



    def CmdLogOff(self):
        if (uicore.Message('AskLogoffGame', {}, uiconst.YESNO, uiconst.ID_YES) == uiconst.ID_YES):
            appUtils.Reboot('Generic Logoff')



    def CmdToggleAudio(self):
        settings.public.audio.Set('audioEnabled', (not settings.public.audio.Get('audioEnabled', 1)))
        if settings.public.audio.audioEnabled:
            uicore.audio.Activate()
        else:
            uicore.audio.Deactivate()
        return True



    def WinCmdToggleWindowed(self):
        uicore.device.ToggleWindowed()
        return True



    def CmdCloseAllWindows(self):
        for wnd in uicore.registry.GetWindows()[:]:
            if not uicore.registry.IsWindow(wnd):
                continue
            if (getattr(wnd, '_killable', False) == True):
                if hasattr(wnd, '_CloseClick'):
                    wnd._CloseClick()
                elif hasattr(wnd, 'CloseX'):
                    wnd.CloseX()
                else:
                    try:
                        wnd.Close()
                    except:
                        log.LogException()
            else:
                if (uiutil.GetAttrs(wnd, 'sr', 'stack') is None):
                    wnd.Minimize()

        return True



    def CmdMinimizeAllWindows(self):
        all = uicore.registry.GetWindows()
        for each in all:
            if (each.sr.stack is not None):
                continue
            if (each.align == uiconst.UI_ALCLIENT):
                continue
            each.Minimize()

        return True



    def CmdMinimizeActiveWindow(self):
        activeWnd = uicore.registry.GetActiveStackOrWindow()
        if activeWnd:
            if ((activeWnd.align == uiconst.UI_ALCLIENT) or (not hasattr(activeWnd, 'Minimize'))):
                return 
            activeWnd.Minimize()
            return True



    def CmdCloseActiveWindow(self):
        activeWnd = uicore.registry.GetActive()
        if (activeWnd and getattr(activeWnd, 'canCloseActiveWnd', 1)):
            if hasattr(activeWnd, 'CloseX'):
                activeWnd.CloseX()
                return True
            if hasattr(activeWnd, 'SelfDestruct'):
                activeWnd.SelfDestruct()
                return True



    def CmdResetMonitor(self):
        uicore.device.ResetMonitor()
        return True



    def OnUp(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnUp')):
            uthread.pool('commandSvc::OnKey OnUp', fa.OnUp)



    def OnDown(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnDown')):
            uthread.pool('commandSvc::OnKey OnDown', fa.OnDown)



    def OnLeft(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnLeft')):
            uthread.pool('commandSvc::OnKey OnLeft', fa.OnLeft)



    def OnRight(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnRight')):
            uthread.pool('commandSvc::OnKey OnRight', fa.OnRight)



    def OnHome(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnHome')):
            uthread.pool('commandSvc::OnKey OnHome', fa.OnHome)



    def OnEnd(self):
        fa = (uicore.registry.GetFocus() or uicore.registry.GetActive())
        if (fa and hasattr(fa, 'OnEnd')):
            uthread.pool('commandSvc::OnKey OnEnd', fa.OnEnd)



    def OnShiftTab(self):
        self.OnTab()



    def OnTab(self):
        oldfoc = uicore.registry.GetFocus()
        if ((oldfoc is None) or (oldfoc == uicore.desktop)):
            prestate = getattr(uicore, 'toggleState', None)
            if prestate:
                for windowID in prestate:
                    wnd = uicore.registry.GetWindow(windowID)
                    if (wnd and (getattr(wnd, '_collapsed', 0) or getattr(wnd, 'collapsed', 0))):
                        wnd.Expand()

                uicore.toggleState = None
                return 
            state = []
            wnds = uicore.registry.GetValidWindows(floatingOnly=True)
            for wnd in wnds:
                if not getattr(wnd, 'windowID', None):
                    continue
                if (getattr(wnd, '_collapsed', 0) or getattr(wnd, 'collapsed', 0)):
                    continue
                windowID = wnd.windowID
                wnd.Collapse()
                state.append(windowID)
                continue

            if not state:
                for wnd in wnds:
                    if (getattr(wnd, '_collapsed', 0) or getattr(wnd, 'collapsed', 0)):
                        wnd.Expand()

            uicore.toggleState = state
            if state:
                return 
        uicore.registry.FindFocus([1, -1][uicore.uilib.Key(uiconst.VK_SHIFT)])



    def OnReturn(self):
        uicore.registry.Confirm()



    def OnCtrlA(self):
        focus = uicore.registry.GetFocus()
        if (focus and hasattr(focus, 'SelectAll')):
            focus.SelectAll()
            return True
        active = uicore.registry.GetActive()
        if (active and hasattr(active, 'SelectAll')):
            active.SelectAll()
            return True



    def OnCtrlC(self):
        focus = uicore.registry.GetFocus()
        if getattr(focus, 'Copy', None):
            return focus.Copy()



    def OnCtrlX(self):
        focus = uicore.registry.GetFocus()
        if getattr(focus, 'Cut', None):
            return focus.Cut()



    def OnCtrlV(self):
        text = uiutil.GetClipboardData()
        if not text:
            return False
        focus = uicore.registry.GetFocus()
        if (focus and hasattr(focus, 'Paste')):
            focus.Paste(text)
            return True



    def OnCtrlTab(self):
        w = self.GetWndMenu()
        if w:
            w.Next()
            return True



    def OnCtrlShiftTab(self):
        w = self.GetWndMenu()
        if w:
            w.Prev()
            return True



    def GetWndMenu(self):
        if uicore.registry.GetModalWindow():
            return 
        else:
            import menu
            if ((not getattr(self, 'chooseWndMenu', None)) or (self.chooseWndMenu.destroyed or (self.chooseWndMenu.state == uiconst.UI_HIDDEN))):
                menu.KillAllMenus()
                wnds = [ each for each in uicore.registry.GetWindows() if not(getattr(each, 'defaultExcludeFromWindowMenu', 0)) ]
                showhide = (uicore.layer.main.state == uiconst.UI_PICKCHILDREN)
                m = []
                for each in wnds:
                    if not hasattr(each, 'Maximize'):
                        continue
                    if hasattr(each, 'GetCaption'):
                        label = each.GetCaption()
                    else:
                        label = each.name
                    m.append((label, each.Maximize))

                if m:
                    mv = menu.CreateMenuView(menu.CreateMenuFromList(m), None, None)
                    (mv.left, mv.top,) = (((uicore.desktop.width - mv.width) // 2), ((uicore.desktop.height - mv.height) // 2))
                    uicore.layer.menu.children.insert(0, mv)
                    self.chooseWndMenu = mv
                    self.wmTimer = base.AutoTimer(10, self._CheckWndMenu)
                else:
                    self.chooseWndMenu = None
            return self.chooseWndMenu



    def _CheckWndMenu(self, *args):
        ctrl = uicore.uilib.Key(uiconst.VK_CONTROL)
        if not ctrl:
            self.wmTimer = None
        chooseWndMenu = getattr(self, 'chooseWndMenu', None)
        if (chooseWndMenu and ((not chooseWndMenu.destroyed) and (chooseWndMenu.state != uiconst.UI_HIDDEN))):
            chooseWndMenu.ChooseHilited()
        self.chooseWndMenu = None



    def OnEsc(self, stopLoading = True):
        if len(uicore.layer.menu.children):
            uiutil.Flush(uicore.layer.menu)
            return True
        modalResult = uicore.registry.GetModalResult(uiconst.ID_CANCEL, 'btn_cancel')
        if (modalResult is not None):
            uicore.registry.GetModalWindow().SetModalResult(modalResult)
            return True
        if (stopLoading and (uicore.layer.loading.state == uiconst.UI_NORMAL)):
            uthread.new(sm.GetService('loading').HideAllLoad)
            return True
        sys = uicore.layer.systemmenu
        if sys:
            if sys.isopen:
                uthread.new(sys.CloseMenu)
            else:
                uthread.new(sys.OpenView)
            return True


    OnEsc_Core = OnEsc

    def PrintScreen(self, *args):
        date = util.FmtDate(blue.os.GetTime(), 'sl')
        date = date.replace(':', '.')
        date = date.replace(' ', '.')
        sur = trinity.device.GetBackBuffer()
        hd = settings.user.ui.hdScreenshots
        (ext, trirender,) = ('jpg', trinity.TRIIFF_JPG)
        if hd:
            (ext, trirender,) = ('bmp', trinity.TRIIFF_BMP)
        path = ('%s/%s/capture/Screenshots/%s.%s' % (blue.win32.SHGetFolderPath(blue.win32.CSIDL_PERSONAL),
         boot.appname,
         date,
         ext))
        sur.SaveSurfaceToFile(path, trirender)
        return True



    def OpenMonitor(self):
        uicore.registry.GetOrCreateWindow(decoClass=uicls.Monitor, parent=uicore.layer.main)
        return True




